package com.xiaocq.wordskiller;

import java.util.Random;
import java.util.TreeSet;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class ChoiceTest extends Activity implements OnClickListener {
	private static final String TAG = "ChoiceTest";
	private boolean isUnitTest = true;

	private Button choiceA, choiceB, choiceC, choiceD;
	private Button backToMenu;
	private EditText displayWords;
	private TextView testProgressShow;

	private ProgressDialog progressDialog;

	private int mTestType;
	private int unitId;

	private boolean isNewTest;
	private int mTestCount;
	private int mFinishedCount;
	private int allWordsCounts;

	private long startTimeInMillis, finishTimeInMillis;
	private long allTimeInMillis;

	private Random random;

	private Cursor cursor, allWords;
	private int maxNumber;
	private int[] details;
	private TreeSet<Integer> checkSet;
	private int nowPosition;

	private int correctId;
	private int selectedId;
	private int[] explains = new int[4];
	String[] options;
	private Intent sendIntent;
	private ActivityHelper helper;

	private Handler loadingHandler = new Handler() {

		public void handleMessage(android.os.Message msg) {
			progressDialog.dismiss();
			prepareWords(nowPosition);
		};
	};
	private Handler savingHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			progressDialog.dismiss();
			startActivity(sendIntent);
			finish();
		};
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.choicetest);

		initComponents();

		Intent intent = getIntent();
		loadOrInit(intent);
	}

	@Override
	protected void onDestroy() {
		cursor.close();
		super.onDestroy();
	}

	private void prepareWords(int position) {
		int cursorId = addAndSaveNewCursorId(position);
		changeOrder();
		options = getOptions(explains, correctId);

		cursor.moveToPosition(cursorId);

		displayWords.setText(cursor.getString(1));

		choiceA.setText(options[0]);
		choiceB.setText(options[1]);
		choiceC.setText(options[2]);
		choiceD.setText(options[3]);

		mFinishedCount = position + 1;

		freshState();

		startTimeInMillis = System.currentTimeMillis();
	}

	private void changeOrder() {
		int index = random.nextInt(4);

		for (int i = 0; i < 4; i++) {
			if (correctId == explains[i]) {
				int tmp = explains[i];
				explains[i] = explains[index];
				explains[index] = tmp;
			}
		}
	}

	private String[] getOptions(int[] indexs, int cID) {
		String[] results = new String[4];
		String[] allExplains;
		int order;
		for (int i = 0; i < 4; i++) {
			if (cID == indexs[i]) {
				correctId = i;
				cursor.moveToPosition(indexs[i]);
				allExplains = cursor.getString(2).split("\\|");
			} else {
				allWords.moveToPosition(indexs[i]);
				allExplains = allWords.getString(2).split("\\|");
			}
			order = random.nextInt(allExplains.length);
			results[i] = allExplains[order];
		}
		return results;
	}

	private int addAndSaveNewCursorId(int position) {
		int cursorId = 0;
		int size = 0;
		boolean isFound = false;
		boolean canAdd = true;
		int tmpCursorPosition;
		int index;
		int realId = 0;
		if (details[position] != 0) {
			cursorId = details[position] % 10000;
			explains[size++] = cursorId;
			correctId = cursorId;
			cursor.moveToPosition(cursorId);
			realId = cursor.getInt(0);
			isFound = true;
		}
		while (!isFound) {
			tmpCursorPosition = random.nextInt(maxNumber);
			if (checkSet.contains(tmpCursorPosition) == false) {
				cursorId = tmpCursorPosition;
				checkSet.add(cursorId);
				explains[size++] = cursorId;
				correctId = cursorId;
				cursor.moveToPosition(cursorId);
				realId = cursor.getInt(0);
				isFound = true;
			}
		}

		isFound = false;
		int otherId;
		while (!isFound) {
			tmpCursorPosition = random.nextInt(allWordsCounts);
			allWords.moveToPosition(tmpCursorPosition);
			otherId = allWords.getInt(0);
			if (realId == otherId)
				continue;
			for (index = 0; index < size; index++) {
				if (explains[index] == tmpCursorPosition) {
					canAdd = false;
					break;
				}
			}
			if (canAdd) {
				explains[size++] = tmpCursorPosition;
				if (size == 4) {
					isFound = true;
				}
			}
		}

		cursor.moveToPosition(cursorId);
		details[position] = cursor.getInt(0) * 100000 + cursorId;

		return cursorId;
	}

	private void loadOrInit(Intent intent) {
		if (CommandList.COSTUM_CHOICE_TEST.equals(intent.getAction())) {
			isUnitTest = false;
			
			isNewTest = intent
					.getBooleanExtra(CommandList.IS_THE_NEW_TEST, true);
			mTestType = intent.getIntExtra(CommandList.COSTUM_TEST_TYPE, 0);
			mTestCount = intent.getIntExtra(CommandList.COSTUM_TEST_COUNTS, 30);
			mFinishedCount = intent.getIntExtra(
					CommandList.COSTUM_FINISHED_COUNTS, 0);
			allTimeInMillis = intent.getLongExtra(CommandList.COSTUM_TIME_COST,
					0L);
		} else if (CommandList.UNIT_CHOICE_TEST.equals(intent.getAction())) {
			isUnitTest = true;
			isNewTest = intent.getBooleanExtra(CommandList.IS_THE_NEW_TEST,
					false);
			unitId = intent.getIntExtra(CommandList.UNIT_ID, 1);
			mFinishedCount = intent.getIntExtra(
					CommandList.UNIT_FINISHED_COUNTS, 0);
			allTimeInMillis = intent
					.getLongExtra(CommandList.UNIT_TIME_COST, 0L);
		}

		random = new Random();
		helper = new ActivityHelper(ChoiceTest.this);
		prepareInBackGround();
	}

	private void prepareInBackGround() {
		progressDialog = new ProgressDialog(ChoiceTest.this);
		progressDialog.setMessage(getText(R.string.tip_loading));
		progressDialog.show();
		new Thread() {
			public void run() {
				prepareCursorData();
				prepareCollections();
				loadingHandler.sendEmptyMessage(0);
			};
		}.start();
	}

	private void prepareCursorData() {
		helper.open();
		if (isUnitTest) {
			cursor = helper.getCursorDataByUnitId(unitId);
			// 单元测试模式的最后一个变量的初始化在这里
			mTestCount = cursor.getCount();
		} else {
			cursor = helper.getCursorDataByType(mTestType);
		}
		allWords = helper.getCursorDataByType(0);
		allWordsCounts = allWords.getCount();
		maxNumber = cursor.getCount();

		helper.close();
	}

	private void prepareCollections() {
		if (isNewTest == true) {
			details = new int[mTestCount];
			checkSet = new TreeSet<Integer>();
			nowPosition = 0;
			return;
		}
		details = helper.getDetailsFromFile(isUnitTest, mTestCount);
		checkSet = helper.getCheckedSet(details, mFinishedCount);
		nowPosition = (mFinishedCount - 1) > 0 ? (mFinishedCount - 1) : 0;
	}

	private void freshState() {
		testProgressShow.setText("进度：" + mFinishedCount + " / " + mTestCount);
	}

	private void initComponents() {
		backToMenu = (Button) findViewById(R.id.choicetest_backToMenu);
		choiceA = (Button) findViewById(R.id.choicetest_choiceA);
		choiceB = (Button) findViewById(R.id.choicetest_choiceB);
		choiceC = (Button) findViewById(R.id.choicetest_choiceC);
		choiceD = (Button) findViewById(R.id.choicetest_choiceD);
		displayWords = (EditText) findViewById(R.id.choicetest_displayWord);
		testProgressShow = (TextView) findViewById(R.id.choicetest_testProgressShow);

		choiceA.setOnClickListener(this);
		choiceB.setOnClickListener(this);
		choiceC.setOnClickListener(this);
		choiceD.setOnClickListener(this);

		backToMenu.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				saveAndQuit();
			}
		});
	}

	public void onClick(View v) {
		int id = v.getId();
		switch (id) {
		case R.id.choicetest_choiceA:
			selectedId = 0;
			break;
		case R.id.choicetest_choiceB:
			selectedId = 1;
			break;
		case R.id.choicetest_choiceC:
			selectedId = 2;
			break;
		case R.id.choicetest_choiceD:
			selectedId = 3;
			break;
		}
		checkAndRecord();
		nowPosition = nowPosition + 1 > mTestCount - 1 ? mTestCount - 1
				: nowPosition + 1;
		if (mFinishedCount >= mTestCount) {
			saveAndJump();
		} else {
			prepareWords(nowPosition);
		}
	}

	private void saveAndQuit() {
		boolean isAllReady = helper.saveIntoFile(details, isUnitTest);
		if (isAllReady) {
			saveControlParam();
		}
		Toast.makeText(ChoiceTest.this, R.string.tip_progressSaved,
				Toast.LENGTH_SHORT).show();
		finish();
	}

	private void saveControlParam() {
		SharedPreferences pref = getSharedPreferences(CommandList.PREF_NAME,
				MODE_PRIVATE);
		SharedPreferences.Editor editor = pref.edit();

		if (isUnitTest) {
			helper.saveUnitTestParam(editor, false, unitId, mFinishedCount,
					allTimeInMillis);
		} else {
			helper.saveOptionalTestParam(editor, false, mTestCount,
					mFinishedCount, mTestType, allTimeInMillis);
		}
	}

	private void checkAndRecord() {
		finishTimeInMillis = System.currentTimeMillis();
		allTimeInMillis += (finishTimeInMillis - startTimeInMillis);
		boolean isCorrect = (selectedId == correctId);
		details[nowPosition] = helper.getWrappedId(details[nowPosition],
				isCorrect);
	}

	private void saveAndJump() {
		progressDialog.setMessage(getText(R.string.tip_saving));
		progressDialog.show();
		new Thread() {
			public void run() {
				long currentTime = System.currentTimeMillis();
				int wrongCounts = helper.updateResult(details, currentTime);
				clearParams();
				sendIntent = new Intent();
				sendIntent.setClass(ChoiceTest.this, ResultShow.class);
				sendIntent.putExtra(CommandList.LATELY_ACCESS, currentTime);
				sendIntent.putExtra(CommandList.WRONG_COUNTS, wrongCounts);
				sendIntent.putExtra(CommandList.ALL_COUNTS, mTestCount);
				sendIntent.putExtra(CommandList.ALL_TIME, allTimeInMillis);
				savingHandler.sendEmptyMessage(0);
			};
		}.start();
	}

	private void clearParams() {
		SharedPreferences pref = getSharedPreferences(CommandList.PREF_NAME,
				MODE_PRIVATE);
		SharedPreferences.Editor editor = pref.edit();
		if (isUnitTest) {
			helper.clearUnitParams(editor, false);
		} else {
			helper.clearOptionalParam(editor, false);
		}
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			saveAndQuit();
		}
		return super.onKeyDown(keyCode, event);
	}
}